package com.songcha.library_common.ui.view

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.graphics.PathMeasure
import android.graphics.PorterDuff
import android.graphics.PorterDuffXfermode
import android.graphics.Rect
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.TextView
import androidx.compose.ui.platform.ComposeView
import com.songcha.library_common.R
import com.songcha.library_common.util.BitmapUtil
import com.songcha.library_common.util.FontUtil
import com.songcha.library_common.util.LogUtil
import com.songcha.library_common.util.ToastUtil
import com.songcha.library_common.util.dp2px
import com.songcha.library_common.util.sp2px
import kotlin.math.absoluteValue
import kotlin.math.floor

class AnnularChatView
@JvmOverloads
constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyle: Int = 0,
    defRes: Int = 0
) : View(context,attrs,defStyle,defRes) {

    private var mRadius=80f.dp2px()
    private var mAnnularStrokeWidth=32f.dp2px()
    private lateinit var mPaint:Paint
    private lateinit var mLinePaint:Paint
    private lateinit var mTextPaint:Paint
    private lateinit var mPath:Path
    private lateinit var mNewPath:Path
    private lateinit var mPathMeasure:PathMeasure
    private var mLineWidth=10f.dp2px()
    private var mLineStrokeWidth=2f.dp2px()
    private var mRightLineWidth=15f.dp2px()
    private var mTextColor=Color.BLACK
    private var mTextSize=16f.sp2px()
    //prevent y exceed scope
    private var mMaxYOffset=30f.dp2px()

    private var mPos=FloatArray(2)
    private var mTan=FloatArray(2)

    private var mTitles=mutableListOf<String>()
    private var mProgress=mutableListOf<Float>()
    private var mColors=mutableListOf<Int>()


    init {
        initView(context, attrs)
    }


    private fun initView(context: Context, attrs: AttributeSet?){

        if(attrs!=null){
            val ta=context.obtainStyledAttributes(attrs, R.styleable.AnnularChatView)
            mRadius=ta.getDimension(R.styleable.AnnularChatView_annular_radius,80f.dp2px())
            mAnnularStrokeWidth=ta.getDimension(R.styleable.AnnularChatView_annular_stroke_width,32f.dp2px())
            mLineWidth=ta.getDimension(R.styleable.AnnularChatView_annular_line_width,10f.dp2px())
            mLineStrokeWidth=ta.getDimension(R.styleable.AnnularChatView_annular_line_stroke_width,2f.dp2px())
            mRightLineWidth=ta.getDimension(R.styleable.AnnularChatView_annular_right_line_width,15f.dp2px())
            mTextColor=ta.getColor(R.styleable.AnnularChatView_annular_text_color,Color.BLACK)
            mTextSize=ta.getDimension(R.styleable.AnnularChatView_annular_text_size,16f.sp2px())
            mMaxYOffset=ta.getDimension(R.styleable.AnnularChatView_annular_text_size,30f.dp2px())
            ta.recycle()
        }

        mPaint=Paint()
        mPaint.isAntiAlias=true
        mPaint.style=Paint.Style.STROKE
        mPaint.strokeWidth=mAnnularStrokeWidth
        mPaint.strokeCap=Paint.Cap.BUTT

        mLinePaint=Paint()
        mLinePaint.isAntiAlias=true
        mLinePaint.style=Paint.Style.STROKE
        mLinePaint.strokeWidth=mLineStrokeWidth
        mLinePaint.color=Color.BLACK

        mTextPaint=Paint()
        mTextPaint.isAntiAlias=true
        mTextPaint.textSize=mTextSize
        mTextPaint.color=mTextColor

        mPath= Path()
        mNewPath=Path()
        mPathMeasure= PathMeasure()

    }

    fun setTitles(titles:MutableList<String>){
        mTitles=titles
    }

    fun setProgress(progress:MutableList<Float>){
        mProgress=progress
    }

    fun setColors(colors:MutableList<Int>){
        mColors=colors
    }


    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        super.onLayout(changed, l, t, r, b)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        if(mTitles.size<1 || mProgress.size!=mTitles.size || mColors.size!=mTitles.size) return
        if(mProgress.sum()<=0) return

        mPath.reset()
        mPaint.color=Color.TRANSPARENT
        mPath.addCircle((width/2).toFloat(),(height/2).toFloat(),mRadius,Path.Direction.CW)
        mPathMeasure.setPath(mPath,false)

        canvas.drawPath(mPath,mPaint)

        var startD=0f
        for(i in 0 until mProgress.size){

            mNewPath.reset()
            var stopD=mProgress[i]/(mProgress.sum()*1.0f)*mPathMeasure.length

            mPathMeasure.getSegment(startD,stopD+startD,mNewPath,true)

            mPaint.color=mColors[i]
            canvas.drawPath(mNewPath,mPaint)

            mPathMeasure.getPosTan(startD+stopD/2,mPos,mTan)

            val startX=mPos[0]
            val startY=mPos[1]
            //tan quadrant:
            /***
             * -  +
             * +  -
             */
            //translate right angel coordinate system to android coordinate system ,
            // the line equation:k=(y1-y2)/(x2-x1)
            val originX=width/2
            val originY=height/2

            val k=((originY-startY)/(startX-originX))

            var stopX=startX

            if(stopX<width/2){
                stopX-=(mAnnularStrokeWidth/2+mLineWidth).toInt()
            }else if(stopX>width/2){
                stopX+=(mAnnularStrokeWidth/2+mLineWidth).toInt()
            }else{

            }

            var stopY=(originY-(stopX-originX)*k) //y1-(x2-x1)*k

            val yOffset=stopY-startY

            if(yOffset.absoluteValue>mMaxYOffset){
                if(yOffset>0){
                    stopY=startY+mMaxYOffset
                }else if(yOffset<0){
                    stopY=startY-mMaxYOffset
                }
            }

            mLinePaint.color=mColors[i]
            canvas.drawLine(startX,startY.toFloat(),stopX,stopY.toFloat(),mLinePaint)

           val startX2=stopX
            val startY2=stopY
            var stopX2=startX2
            if(startX2<width/2){
                stopX2-=mRightLineWidth
            }else if(startX2>width/2){
                stopX2+=mRightLineWidth
            }
            val stopY2=startY2

            canvas.drawLine(stopX,stopY,stopX2,stopY2,mLinePaint)

            //draw text
            var textX=stopX2
            var textY=stopY2

           val textBound=FontUtil.getTextBounds(mTitles[i],mTextPaint)

           if(textBound!=null){
               val textWidth=textBound.width()
               if(textX<width/2){
                   textX-=(textWidth+5.dp2px())
               }else if(textX>width/2){
                   textX+=5.dp2px()
               }else{
                   textX-=(textWidth/2)
               }

               //val textHeight=fm.bottom.absoluteValue+fm.top.absoluteValue
               val textHeight=textBound.height()
               if(textY<height/2){
                   textY+=textHeight/2
               }else if(textY>height/2){
                   textY+=textHeight/2
               }else{

               }
           }

            canvas.drawText(mTitles[i],textX,textY,mTextPaint)

            startD+=stopD

        }

    }


}